package com.jxsr.algorithm;

import com.jxsr.exception.LimitationException;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description : 漏桶算法
 * @Author : Bruce Lee
 * @CreateTime : 2024/12/26
 */


@Slf4j
public class LeakyBucketRateLimiter {

    // 当前水量
    private static int water = 0;

    // 上次漏水时间
    private static long lastTime;


    public synchronized static boolean tryAcquire(int capacity, double rate) {

        // 漏桶里面没有水
        if(water == 0) {
            lastTime = System.currentTimeMillis();
            if (water < capacity) {
                water++;
                return true;
            }else {
                // 漏桶已满；
                log.error("超过请求次数，请稍后再试");
                throw new LimitationException("超过请求次数，请稍后再试");
            }
        }

        // 先执行漏水
        long now = System.currentTimeMillis();
        int outflow = (int) ((now - lastTime)/1000 * rate);

        // 漏水后的水量
        water = Math.max(0, water - outflow);

        if(water < capacity) {
            water++;
            lastTime = now;
            return true;
        } else {
            log.error("超过请求次数，请稍后再试");
            throw new LimitationException("超过请求次数，请稍后再试");
        }

    }


}
